package com.tnovoselec.android.common.async.runner;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import com.tnovoselec.android.common.async.listener.ResultListener;


public interface Runner {

	/**
	 * Enqueues a task to be processed by the runner.
	 * 
	 * @param key 
	 *        A key to identify the task by. The key will be passed to the
	 *        result listener on the task's completion, so it can be used to
	 *        determine which task has finished in the case of one listener
	 *        being registered against multiple tasks. Can be null.
	 * @param future 
	 *        Represents the future result of the computation. This object will
	 *        - when its {@link Callable#call()} method is invoked - calculate
	 *        and return some result which is to be passed to the result listener.
	 * @param listener
	 *        A listener who will be informed when the operation encapsulated by
	 *        the {@code Callable} argument has completed.
	 * @return A future hosting the provided {@code Callable}. The computation
	 *         can be cancelled, or the result accessed via this {@code Future}.
	 */
	public <K, T> Future<T> doAsync(K key, Callable<T> future, ResultListener<K, T> listener);

	/**
	 * Enqueues a task to be processed by the runner.
	 * 
	 * @param key 
	 *        A key to identify the task by. The key will be passed to the
	 *        result listener on the task's completion, so it can be used to
	 *        determine which task has finished in the case of one listener
	 *        being registered against multiple tasks. Can be null.
	 * @param future 
	 *        Represents the future result of the computation. This object will
	 *        - when its {@link Future#get()} method is invoked - calculate
	 *        and return some result which is to be passed to the result
	 *        listener.
	 * @param listener
	 *        A listener who will be informed when the operation encapsulated by
	 *        the {@code Future} argument has completed.
	 * @return (For convenience) the same {@link Future} passed into this
	 *         method. The computation can be cancelled, or the result accessed via this {@code Future}.
	 */
	public <K, T, F extends Future<T> & Runnable> F doAsync(K key, F future, ResultListener<K, T> listener);
}
